﻿//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------

using UGFExtensions;
using GameFramework.DataTable;
using GameFramework.Event;
using UnityGameFramework.Runtime;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;

namespace Cheng
{
    public class ProcedureChangeScene : ProcedureBase
    {
        private const int MenuSceneId = 0;

        private bool m_ChangeToMenu = false;
        private bool m_IsChangeSceneComplete = false;
        private int m_BackgroundMusicId = 0;
        private bool m_ChangeToLoad = false;
        private string battleName = null;
        public override bool UseNativeDialog
        {
            get
            {
                return false;
            }
        }

        protected override void OnEnter(ProcedureOwner procedureOwner)
        {
            base.OnEnter(procedureOwner);

            m_IsChangeSceneComplete = false;
            GameEntry.Gamefacade.previousScene = SceneManager.GetActiveScene().name;
            //GameEntry.Gamefacade.previousPostion = GameEntry.Gamefacade.previousScene=="Logo"?Vector3.negativeInfinity: PlayerManagr.Instance.transform.localPosition;
            GameEntry.Event.Subscribe(LoadSceneSuccessEventArgs.EventId, OnLoadSceneSuccess);
            GameEntry.Event.Subscribe(LoadSceneFailureEventArgs.EventId, OnLoadSceneFailure);
            GameEntry.Event.Subscribe(LoadSceneUpdateEventArgs.EventId, OnLoadSceneUpdate);
            GameEntry.Event.Subscribe(LoadSceneDependencyAssetEventArgs.EventId, OnLoadSceneDependencyAsset);

            string sceneName = procedureOwner.GetData<VarString>("NextSceneId");
            if (!sceneName.Equals("Load"))
            {
                // 停止所有声音
                GameEntry.Sound?.StopAllLoadingSounds();
                GameEntry.Sound?.StopAllLoadedSounds();

                // 隐藏所有实体
                GameEntry.Entity.HideAllLoadingEntities();
                GameEntry.Entity.HideAllLoadedEntities();
            }

            // 卸载所有场景
            string[] loadedSceneAssetNames = GameEntry.Scene.GetLoadedSceneAssetNames();
            for (int i = 0; i < loadedSceneAssetNames.Length; i++)
            {
                GameEntry.Scene.UnloadScene(loadedSceneAssetNames[i]);
            }

            // 还原游戏速度
            GameEntry.Base.ResetNormalGameSpeed();
           
            battleName = procedureOwner.HasData("BattleName")?procedureOwner.GetData<VarString>("BattleName").ToString():null;
            //sceneName = sceneName.IsNullOrEmpty() ? "Start" : sceneName;
            //m_ChangeToMenu = sceneId == MenuSceneId;
            IDataTable<DRScene> dtScene = GameEntry.DataTable.GetDataTable<DRScene>();
            DRScene drScene = dtScene.GetDataRow((d) => d.AssetName.Equals(sceneName));
            if (drScene == null)
            {
                Log.Warning("Can not load scene '{0}' from data table.", drScene.AssetName);
                return;
            }
            var scenes = GameEntry.Scene.GetUnloadingSceneAssetNames();
            //GameEntry.Scene.LastScene = scenes.Length == 0 ? null : scenes.Last();
            if (drScene.AssetName.Equals("Load"))
                m_ChangeToLoad = true;
            GameEntry.Scene.LoadScene(AssetUtility.GetSceneAsset(drScene.AssetName), Constant.AssetPriority.SceneAsset, this);
            m_BackgroundMusicId = drScene.BackgroundMusicId;
            GameEntry.UI.OpenUIForm(UIFormId.LoadingForm, this);
        }

        protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
        {
            GameEntry.Event.Unsubscribe(LoadSceneSuccessEventArgs.EventId, OnLoadSceneSuccess);
            GameEntry.Event.Unsubscribe(LoadSceneFailureEventArgs.EventId, OnLoadSceneFailure);
            GameEntry.Event.Unsubscribe(LoadSceneUpdateEventArgs.EventId, OnLoadSceneUpdate);
            GameEntry.Event.Unsubscribe(LoadSceneDependencyAssetEventArgs.EventId, OnLoadSceneDependencyAsset);

            base.OnLeave(procedureOwner, isShutdown);
        }

        protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);

            if (!m_IsChangeSceneComplete)
            {
                return;
            }
           
            if (m_ChangeToMenu)
            {
                //ChangeState<ProcedureMenu>(procedureOwner);
            }
            else if (m_ChangeToLoad)
            {
                m_ChangeToLoad = false;
                Debug.Log(1);
                procedureOwner.SetData("NextSceneId", procedureOwner.GetData<VarString>("LoadScene"));
                ChangeState<ProcedureChangeScene>(procedureOwner);
            }
            else
            {
                //procedureOwner.SetData<VarInt32>("NextSceneId", GameEntry.Config.GetInt("Scene.Main"));
                procedureOwner.SetData<VarByte>("GameMode", (byte)GameMode.Survival);

                ChangeState<ProcedureMain>(procedureOwner);
            }
        }

        private void OnLoadSceneSuccess(object sender, GameEventArgs e)
        {
            LoadSceneSuccessEventArgs ne = (LoadSceneSuccessEventArgs)e;
            if (ne.UserData != this)
            {
                return;
            }

            Log.Info("Load scene '{0}' OK.", ne.SceneAssetName);

            if (m_BackgroundMusicId > 0)
            {
                //GameEntry.Sound.PlayMusic(m_BackgroundMusicId);
            }


            GameEntry.Event.Fire(this, CustomBaseEventArgs.Create("MoveAnimationStop", "Int-State-0"));
          
            GameEntry.UI.CloseAllLoadedUIForms();
            //GameEntry.UI.OpenUIForm(UIFormId.PlayerContralForm,this);
            m_IsChangeSceneComplete = true;
           
            ////if(ne.SceneAssetName.Equals("Assets/GameMain/Scenes/Battle.unity"))
            ////{
            ////    var combatFlow = EGamePlay.MasterEntity.Instance.AddChild<CombatFlow>();
            ////    combatFlow.ToEnd();
            ////    combatFlow.JumpToTime = 600;
            ////    if (battleName.IsNullOrEmpty())
            ////    {
            ////        combatFlow.Startup();
            ////    }
            ////    else
            ////    {
            ////        combatFlow.Startup(battleName);
            ////    }
            ////}

        }

        private void OnLoadSceneFailure(object sender, GameEventArgs e)
        {
            LoadSceneFailureEventArgs ne = (LoadSceneFailureEventArgs)e;
            if (ne.UserData != this)
            {
                return;
            }

            Log.Error("Load scene '{0}' failure, error message '{1}'.", ne.SceneAssetName, ne.ErrorMessage);
        }

        private void OnLoadSceneUpdate(object sender, GameEventArgs e)
        {
            LoadSceneUpdateEventArgs ne = (LoadSceneUpdateEventArgs)e;
            if (ne.UserData != this)
            {
                return;
            }

            Log.Info("Load scene '{0}' update, progress '{1}'.", ne.SceneAssetName, ne.Progress.ToString("P2"));
        }

        private void OnLoadSceneDependencyAsset(object sender, GameEventArgs e)
        {
            LoadSceneDependencyAssetEventArgs ne = (LoadSceneDependencyAssetEventArgs)e;
            if (ne.UserData != this)
            {
                return;
            }

            Log.Info("Load scene '{0}' dependency asset '{1}', count '{2}/{3}'.", ne.SceneAssetName, ne.DependencyAssetName, ne.LoadedCount.ToString(), ne.TotalCount.ToString());
        }
    }
}
